package graphics.rasterizing.model;

import static util.MatrixOperationsF.cloo;
import static util.MatrixOperationsF.multiply;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import util.MatrixOperationsF;
import util.Transformations;

public class IndexedTriangleMesh implements Model {
	private int[][] _triangles;
	private float[][] _vertices;
	private float[][] _color;

	private IndexedTriangleMesh() {

	}

	public IndexedTriangleMesh(int[][] triangles, float[][] vertices,
			float[][] colors) {
		_triangles = cloo(triangles);
		_vertices = cloo(vertices);
		_color = cloo(colors);
	}

	public Iterator<Triangle> getIterator() {
		final int[][] tries = _triangles;
		final float[][] vertc = _vertices;
		final float[][] colo = _color;
		return new Iterator<Triangle>() {
			int currentTriangle = 0;

			@Override
			public boolean hasNext() {
				return currentTriangle < tries.length;
			}

			@Override
			public Triangle next() {
				float[][] verts = new float[3][4];
				float[][] color = new float[3][4];
				int[] trie = tries[currentTriangle];
				for (int i = 0; i < trie.length; i++) {
					verts[i] = cloo(vertc[trie[i]]);
					color[i] = null;//cloo(colo[trie[i]]);
				}
				return new Triangle(verts, color);
			}

			@Override
			public void remove() {
				throw new UnsupportedOperationException(
						"This is a read only view");

			}
		};

	}

	@Override
	public Collection<Triangle> getTriangles() {
		ArrayList<Triangle> triangles = new ArrayList<Triangle>();
		Iterator<Triangle> it = getIterator();
		while (it.hasNext())
			triangles.add(it.next());
		return triangles;
	}

	public IndexedTriangleMesh transform(float[][] transformation) {
		IndexedTriangleMesh rv = new IndexedTriangleMesh();
		rv._color = cloo(_color);
		rv._triangles = cloo(_triangles);
		rv._vertices = new float[_vertices.length][];
		for (int i = 0; i < _vertices.length; i++)
			rv._vertices[i] =MatrixOperationsF.homogenize(multiply(transformation, _vertices[i]));
		return rv;
	}
}
